package com.huan.rss.bean;

import org.apache.log4j.Logger;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

/**
 * 利用SAX解析RSS数据
 */
public class RSSDataCapturer extends DefaultHandler{
    Logger logger = Logger.getLogger(RSSDataCapturer.class.getName());//日志记录器
    private List<CommonInformationItem> list;

    private CommonInformationItem item;
    private String source;//rss源
    private int status;//当前解析元素状态
    private StringBuffer buffer;//存储元素内容
    private DateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z", Locale.ENGLISH);

    public static void main(String[] args) {
        String path = "";
        RSSDataCapturer rssDataCapturer = new RSSDataCapturer("知乎rss");
        List<CommonInformationItem> list = rssDataCapturer.load(path);
        for (CommonInformationItem i:list) {
            System.out.println(i);
        }
        System.out.println("总共得到："+list.size()+"条新闻");
    }

    public RSSDataCapturer(String source){
        this.source = source;
        buffer = new StringBuffer();
    }

    /**
     * 解析XML文件，得到item列表
     * @param source
     * @return
     */
    public List<CommonInformationItem> load(String source){
        try{
            //SAX解析流程
            //1. 创建SAX解析器工厂
            SAXParserFactory factory = SAXParserFactory.newInstance();
            //2. 注册事件处理器
            SAXParser parser = factory.newSAXParser();
            //3. 解析XML文件
            parser.parse(source, this);
        }catch (Exception e){
            e.printStackTrace();
            logger.error("解析XML文件失败");
        }
        return list;
    }


    //文件开始
    @Override
    public void startDocument() throws SAXException {
        logger.debug("开始解析XML文件");
        list = new ArrayList<>();
        super.startDocument();
    }

    //文件结束
    @Override
    public void endDocument() throws SAXException {
        logger.debug("结束解析XML文件");
        super.endDocument();
    }


    private final int STATUS_TITLE = 1;
    private final int STATUS_LINK = 2;
    private final int STATUS_DESCRIPTION = 3;
    private final int STATUS_PUBDATE = 4;
    private final int STATUS_GUID = 5;
    //元素开始
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        logger.debug("元素开头："+uri+","+localName+","+qName+","+attributes);
        //记录当前解析的标签
        if (item!=null && qName.equalsIgnoreCase("title")){
            status = STATUS_TITLE;
        }else if (item!=null && qName.equalsIgnoreCase("link")){
            status = STATUS_LINK;
        }else if (item!=null && qName.equalsIgnoreCase("description")){
            status = STATUS_DESCRIPTION;
        }else if (item!=null && qName.equalsIgnoreCase("pubDate")){
            status = STATUS_PUBDATE;
        }else if (item!=null && qName.equalsIgnoreCase("guld")){
            status = STATUS_GUID;
        }else if (qName.equalsIgnoreCase("item")){
            item = new CommonInformationItem();
            item.setSource(this.source);
        }
    }

    //元素结束
    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        logger.debug("元素结尾："+uri+","+localName+","+qName);
        if (item!=null && qName.equalsIgnoreCase("title")){
            item.setTitle(buffer.toString());
            status = 0;
        }else if (item!=null && qName.equalsIgnoreCase("link")){
            item.setLink(buffer.toString());
            status = 0;
        }else if (item!=null && qName.equalsIgnoreCase("description")){
            item.setDescription(buffer);
            status = 0;
        }else if (item!=null && qName.equalsIgnoreCase("pubDate")){
            item.setPubDate(buffer.toString());
            try {
                item.setDate(dateFormat.parse(buffer.toString().trim()));
            } catch (ParseException e) {
                logger.error(e);
            }
            status = 0;
        }else if (item!=null && qName.equalsIgnoreCase("guld")){
            item.setId(buffer.toString());
            status = 0;
        }else if (qName.equalsIgnoreCase("item")){
            if (item.getId()==null){
                item.setId(item.getDescription().hashCode()+"");
            }
            list.add(item);
            item = null;
        }
        buffer = new StringBuffer();
    }

    //元素内容
    @Override
    public void characters(char[] ch,  int start, int length) throws SAXException {
       String txt = new String(ch,start,length);
       logger.debug("元素内容："+txt);
       buffer.append(txt);
    }
}
